package com.seguriapp.controller;

import java.util.Date;
import java.util.List;

import net.sf.json.JSONException;
import net.sf.json.JSONObject;

import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.seguriapp.entities.Alert;
import com.seguriapp.services.AlertService;
import com.seguriapp.util.SearchFilterEntity;
import com.seguriapp.util.Util;

/**
 * Represents the controller for the alerts entities
 * 
 * @author Tania Gonzales(taniadgv@gmail.com)
 */
@Controller
@RequestMapping("/alert")
public class AlertController {

  private static final Logger LOGGER = Logger.getLogger(AlertController.class);

  @Autowired
  private AlertService alertService;

  private long totalPages;

  @RequestMapping(value = "/list", method = RequestMethod.POST)
  @ResponseBody()
  public String getAlertsList(final @RequestBody String searchOptionsJs) {
    final List<Alert> alertList = getAlertsData(searchOptionsJs);
    if (alertList != null) {
      LOGGER.info("Size of alerts list : " + alertList.size());
      return Util.parseEntityListToJson("alerts", alertList, totalPages);
    }
    return StringUtils.EMPTY;
  }

  @RequestMapping(value = "/save", method = RequestMethod.POST)
  @ResponseBody()
  public String saveAlert(final @RequestBody String alertJs) {
    final String errorMessage = alertService.saveAlert(getJsonAlertDataFromString(alertJs));
    final JSONObject obj = new JSONObject();
    if (errorMessage != null) {
      try {
        obj.put("errorMessage", errorMessage);
        return obj.toString();
      } catch (JSONException e) {
        LOGGER.error("Error converting error message to json \n", e);
        return Util.FALSE;
      }
    }
    return Util.TRUE;
  }

  private List<Alert> getAlertsData(final String searchOptionsJs) {
    LOGGER.info("Request for alerts: " + searchOptionsJs);
    if (searchOptionsJs == null || searchOptionsJs.isEmpty()) {
      return null;
    }
    final JSONObject root = JSONObject.fromObject(searchOptionsJs);
    if (root.has(Util.PAGE) && root.has("latitude") && root.has("longitude") && root.has(Util.PAGE_SIZE) && root.has(Util.ASCENDING)
        && root.has("searchByPolStation") && root.has("distance") && root.has("policeStationId")) {
      final Date startDate = root.has("startDate") ? Util.parseStringToDate(root.getString("startDate")) : null;
      final Date endDate = root.has("endDate") ? Util.parseStringToDate(root.getString("endDate")) : null;
      final String names = root.has("names") ? root.getString("names") : null;
      final Long userId = root.has("userId") ? root.getLong("userId") : null;

      final String columnSort = root.has(Util.COLUMN_SORT) ? root.getString(Util.COLUMN_SORT) : null;

      final SearchFilterEntity searchFilter = new SearchFilterEntity(startDate, endDate, names, root.getDouble("latitude"),
          root.getDouble("longitude"), root.getInt("distance"), root.getLong("policeStationId"), root.getBoolean("searchByPolStation"),
          root.getInt(Util.PAGE), root.getInt(Util.PAGE_SIZE), root.getBoolean(Util.ASCENDING), columnSort, userId);
      totalPages = alertService.getAlertsTotalPages(searchFilter);
      return alertService.listAlertsOrderByColumn(searchFilter);
    }
    return null;
  }

  private Alert getJsonAlertDataFromString(final String alertJs) {
    LOGGER.info("Save alert: " + alertJs);
    if (alertJs == null || alertJs.isEmpty()) {
      return null;
    }
    final JSONObject root = JSONObject.fromObject(alertJs);
    final Alert alert = new Alert();
    if (root.has("names") && root.has("lastNames") && root.has("dni") && root.has("latitude") && root.has("longitude") && root.has("postalCode") && root.has("address")) {
      alert.setNames(root.getString("names"));
      alert.setLastNames(root.getString("lastNames"));
      alert.setLatitude(root.getDouble("latitude"));
      alert.setLongitude(root.getDouble("longitude"));
      alert.setDni(root.getString("dni"));
      alert.setPhone(root.has("phone") ? root.getString("phone") : null);
      alert.setPostalCode(root.getString("postalCode"));
      alert.setDate(new Date());
      alert.setAddress(root.getString("address"));
    } else {
      LOGGER.info("Alert does not have fields: names, lastNames, dni, latitude, longitude, postalCode, address");
      return null;
    }
    if (root.has("id")) {
      alert.setId(root.getLong("id"));
      if (alert.getId() == 0) {
        alert.setId(null);
      }
    }
    return alert;
  }

}
